package com.multicampus.simplewiki.parser;

import java.util.HashMap;
import java.util.Map;

public class WikiTokenizer {
	private String contents;
	private int currentPos;
	private int tokenCount;
	private Map<Integer, WikiToken> cache;

	public WikiTokenizer(String contents) {
		super();
		this.contents = contents;
		this.currentPos = 0 ;
		tokenCount = 1;
		
		cache = new HashMap<Integer, WikiToken>();
	}
	
	public void setCurrent(WikiToken token){
		currentPos = token.getEndPosition();
		tokenCount = token.getOrder() + 1;
	}
	
	public WikiToken getPrevToken(int i){
		return cache.get(i);
	}
	
	public int getTokenCount() {
		return tokenCount;
	}

	public WikiToken nextToken(){
		char c;
		int startPosition = currentPos;

		while(currentPos < contents.length()){
			c = contents.charAt(currentPos);
			
			if(isEmphasis(c)){
				if(currentPos > startPosition)
					return makeToken(startPosition, currentPos, 0);
				
				return makeToken(startPosition, ++currentPos, 1);
			}
			
			if(isEscape(c)){
				if(currentPos > startPosition)
					return makeToken(startPosition, currentPos, 0);
				
				return makeToken(startPosition, ++currentPos, 6);
			}
			
			if(isFormatStart(c)){
				if(currentPos > startPosition)
					return makeToken(startPosition, currentPos, 0);
				
				currentPos = currentPos + 3;
				return makeToken(startPosition, currentPos, 2);
			}
			
			if(isLink(c)){
				if(currentPos > startPosition)
					return makeToken(startPosition, currentPos, 0);
				
				return makeToken(startPosition, ++currentPos, 4);
			}
			
			if(c == '\n'){
				if(currentPos > startPosition)
					return makeToken(startPosition, currentPos, 0);
				
				return makeToken(startPosition, ++currentPos, 3);
			}
			
			currentPos++;
		}
		
		if(currentPos > startPosition)
			return makeToken(startPosition, currentPos, 0);
		
		return null;
	}
	
	private WikiToken makeToken(int startPosition, int endPosition, int type){
		WikiToken token = new WikiToken();
		token.setStartPosition(startPosition);
		token.setEndPosition(endPosition);
		token.setContents(contents.substring(startPosition, endPosition));
		token.setType(type);
		token.setOrder(tokenCount++);
		
		cache.put(token.getOrder(), token);
		
		return token;
	}
	
	private boolean isFormatStart(char c) {
		if(c == 'h'){
			char nextChar = contents.charAt(currentPos + 1);
			if(currentPos == 0 || contents.charAt(currentPos - 1) == '\n'){
				if(nextChar == '1' || nextChar == '2' || nextChar == '3' || nextChar == '4' || nextChar == '5'){
					nextChar = contents.charAt(currentPos + 2);
					
					if(nextChar == '.')
						return true;
				}
			}
		}
		
		return false;
	}
	
	private boolean isEscape(char c){
		if(c == '\\') return true;
		
		return false;
	}

	private boolean isEmphasis(char c){
		if(c == '*' || c == '_' || c == '+' || c == '-'){
			return true;
		}
		else
			return false;
	}
	
	private boolean isLink(char c){
		if(c == '[' || c == ']')
			return true;
		else
			return false;
	}
}
